package com.mzj.saas.mservice.smartlock.service.xizhao;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.mzj.saas.commons.*;
import com.mzj.saas.mservice.lock.entity.SmartLockCard;
import com.mzj.saas.mservice.lock.entity.SmartLockPwd;
import com.mzj.saas.mservice.lockManager.entity.SmartLockBrand;
import com.mzj.saas.mservice.lockManager.repository.SmartLockBrandRepository;
import com.mzj.saas.mservice.smartlock.sgin.RSAUtils;
import com.mzj.saas.mservice.smartlock.vo.*;
import com.mzj.saas.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.*;

/**
 * 熙照-智能锁接口
 * 
 * @author shun
 * @createDate: 2021年6月26日 下午3:10:56
 * @version: 1.0
 *
 */
@Service
public class SmartLockXzService {

	private static final Logger log = LoggerFactory.getLogger(SmartLockXzService.class);
	@Value("${xizhao.lock.callback.url}")
	private String xizhaoLockCallbackUrl;
	@Autowired
	private SSLNetProvider httpClient;
	@Autowired
	private RedisService redisService;
	@Autowired
	private SmartLockBrandRepository smartLockBrandRepository;

	/**
	 * 封装请求头
	 * 
	 * @param brand
	 * @return
	 * @author shun
	 * @date 2021年6月26日
	 */
	public SmartLockApiHeaderVO getApiHeader(SmartLockBrand brand) {
		// 获取门锁信息
		String sid = brand.getSid();
		String sercret = brand.getSercret();

		// 封装请求头参数
		SmartLockApiHeaderVO vo = new SmartLockApiHeaderVO();
		vo.setSid(sid);
		vo.setxNonce(RandomNoUtils.getRandomStringByLength(35));
		vo.setxTimestamp(String.valueOf(System.currentTimeMillis()));

		String sign = RSAUtils.xzSign(sid, vo.getxTimestamp(), vo.getxNonce(), sercret);
		vo.setxSign(sign);
		return vo;
	}

	/**
	 * 获取index
	 * 
	 * @param lockId
	 *            锁id/sn
	 * @param pwdSeq
	 *            密码/卡/指纹序号
	 * @param card
	 *            卡号
	 * @param brandId
	 *            品牌id
	 * @param pwdType
	 *            密码类型1密码 2卡 3指纹
	 * @return
	 * @author shun
	 * @date 2021年6月28日
	 */
	public ResultBean<String> getSmartLockIndex(String lockId, String pwdSeq, String card, Long brandId,
			Integer pwdType) {
		try {
			if (lockId == null || (lockId != null && pwdSeq == null && card == null) || brandId == null) {
				log.info("参数错误, lockId={}， pwdSeq={}, card={}, brandId={}", lockId, pwdSeq, card, brandId);
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "smartLock/device/index";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, String> map = new HashMap<>();
			map.put("lockId", lockId);
			if (StringUtils.isNoneEmpty(pwdSeq)) {
				map.put("pwdSeq", pwdSeq);
			} else if (StringUtils.isNoneEmpty(card)) {
				map.put("pwdSeq", card);
			}

			// 接口调用
			log.info("body={}", JSON.toJSONString(map));
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);

			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}

			JSONObject object = JSONObject.parseObject("data");
			Integer total = Integer.parseInt(object.getString("result"));
			if (total == null || total <= 0) {
				return ResultBean.failedResultOfParamWithMsg("数据为空");
			}
			List<SmartLockIndexVO> dataArray = JSONArray.parseArray(object.getString("result"), SmartLockIndexVO.class);
			for (SmartLockIndexVO svo : dataArray) {
				if ("code".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				} else if ("adminpwd".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				} else if ("dynamicpwd".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				} else if ("fingerprint".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				} else if ("card".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				} else if ("unknow".equals(svo.getPwdType())) {
					return ResultBean.successfulResult(svo.getPwdIndex().toString());
				}
			}
			return ResultBean.failedResultOfParamWithMsg("数据为空");
		} catch (Exception e) {
			log.error("获取index设备异常" + e.getMessage(), e);
			return ResultBean.failedResultOfException();
		}

	}

	/**
	 * 注册设备事件消息推送地址
	 * 
	 * @param vo
	 * @return
	 */
	public ResultBean<String> callBackRegister(Long brandId) {
		try {
			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "event/callback/register";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, String> map = new HashMap<>();
			map.put("callbackUrl", xizhaoLockCallbackUrl);

			// 接口调用
			log.info("body={}", JSON.toJSONString(map));
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 注册设备事件消息推送地址, map={}, resultStr={}", JSON.toJSONString(map), JSON.toJSONString(resultStr));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			return ResultBean.successfulResult(null);
		} catch (Exception e) {
			log.error("注册设备事件消息推送地址异常" + e.getMessage(), e);
			return ResultBean.failedResultOfException();
		}
	}

	/**
	 * 注册NB新设备
	 * 
	 * @param vo
	 * @return
	 */
	public ResultBean<String> bindimei(String imei, String deviceName, Long brandId) {
		try {
			if (StringUtils.isBlank(imei)) {
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/bindimei";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, String> map = new HashMap<>();
			map.put("imei", imei);
			map.put("deviceName", deviceName);

			// 接口调用
			log.info("body={}", JSON.toJSONString(map));
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			log.info("熙照, 注册NB新设备, map={}, resultStr={}", JSON.toJSONString(map), JSON.toJSONString(resultStr));
			if ("HTTP Status 404".contains(resultStr)) {
				return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
			}
			JSONObject result = JSONObject.parseObject(resultStr);

			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}

			// 熙照没有sn, 可以直接通过imei操作业务
			return ResultBean.successfulResult(imei);
		} catch (Exception e) {
			log.error("注册NB新设备异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 获取门锁信息
	 * 
	 * @param sn
	 * @param brandId
	 * @return
	 * @author shun
	 * @date 2021年7月1日
	 */
	public ResultBean<DevMacStateVO> getState(String sn, Long brandId) {
		try {
			if (StringUtils.isBlank(sn)) {
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/info/" + sn;

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 接口调用
			String resultStr = httpClient.httpGet(url, vo);
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 获取门锁信息, sn={}, result={}", sn, JSON.toJSONString(result));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			DevMacStateVO data = new DevMacStateVO();
			JSONObject object = result.getJSONObject("data");
			// online/offline
			String state = object.getString("status");
			Integer power = object.getInteger("power");

			data.setBattery(power);
			if ("online".equals(state)) {
				data.setState(1);
			} else {
				data.setState(2);
			}
			data.setStatus(1);
			data.setLockSn(sn);
			return ResultBean.successfulResult(data);
		} catch (Exception e) {
			log.error("获取锁状态异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 查询动态密码
	 * 
	 * @param vo
	 * @return
	 */
	public ResultBean<List<DynamicPasswordVO>> getDynamicPassword(String sn, Long brandId) {
		try {
			if (StringUtils.isBlank(sn)) {
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/dynamicPwd/" + sn;

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 接口调用
			String resultStr = httpClient.httpGet(url, vo);
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 查询动态密码, sn={}, result={}", sn, JSON.toJSONString(result));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject object = result.getJSONObject("data");
			List<DynamicPasswordVO> dataArray = new ArrayList<>();
			DynamicPasswordVO passwordVO = new DynamicPasswordVO();
			passwordVO.setPassword(object.getString("dynamicpwd"));
			dataArray.add(passwordVO);
			return ResultBean.successfulResult(dataArray);
		} catch (Exception e) {
			log.error("查询动态密码异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 密码统一处理
	 * 
	 * @param smartLockCard
	 * @param vo
	 * @param brandId
	 * @return
	 * @author shun
	 * @date 2021年7月1日
	 */
	public ResultBean<String> validateOperationTypeAndPassword(SmartLockPwd smartLockPwd, SmartLockVO vo,
			Long brandId) {
		if(smartLockPwd != null && smartLockPwd.getPwdIndexNum() != null){
			vo.setIndexNum(smartLockPwd.getPwdIndexNum());
		}
		
		// 新增
		if (smartLockPwd == null || smartLockPwd.getId() == null) {
			return operationPassword(vo, brandId);
		} else if (smartLockPwd.getId() != null) {
			// 次数不能修改
			if ("5".equals(vo.getAuthType())) {
				return ResultBean.failedResultOfParamWithMsg("设备不支持修改次数");
			}
			// 修改内容
			updatePassword(vo, brandId);

			// 修改时间
			updatePasswordTime(vo, brandId);
		}

		return ResultBean.successfulResult(null);
	}

	/**
	 * 新增密码
	 * 
	 * @param accessToken
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> operationPassword(SmartLockVO lockVO, Long brandId) {
		try {
			log.info("熙照, 新增密码, vo={}", JSON.toJSONString(lockVO));
			if (StringUtils.isBlank(lockVO.getSn()) || StringUtils.isBlank(lockVO.getPassword())
					|| StringUtils.isBlank(lockVO.getAuthType()) || StringUtils.isBlank(lockVO.getStartTime())
					|| StringUtils.isBlank(lockVO.getEndTime())) {
				log.info("参数错误, sn={}, password={}, authType={}, startTime={}, endTime={}", lockVO.getSn(),
						lockVO.getPassword(), lockVO.getAuthType(), lockVO.getStartTime(), lockVO.getEndTime());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			if ((lockVO.getPasswordType() == null || lockVO.getPasswordType() == 1) && lockVO.getAuthInfoId() == null) {
				return ResultBean.failedResultOfParamWithMsg("授权ID为空");
			}

			if ("5".equals(lockVO.getAuthType()) && (lockVO.getTimes() == null || lockVO.getTimes() > 1)) {
				if(lockVO.getTimes() > 1){
					log.info("熙照, 自定义密码次数错误, 不支持自定义次数, sn={}, times={}", lockVO.getSn(), lockVO.getTimes());
					return ResultBean.failedResultOfParamWithMsg("锁品牌, 不支持自定义次数");
				}
				return ResultBean.failedResultOfParamWithMsg("密码次数, 参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/savePwd";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", lockVO.getSn());
			map.put("password", LockAESUtil.encryption(lockVO.getPassword(), brand.getSid()));
			map.put("startTime",
					DateUtils.format(lockVO.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("endTime",
					DateUtils.format(lockVO.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));

			if ("5".equals(lockVO.getAuthType())) {
				map.put("times", lockVO.getTimes());
			} else {
				map.put("times", -1);
			}
			map.put("pwdSeq", String.valueOf(lockVO.getIndex()));

			// 接口调用
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 新增密码, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码需要缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(lockVO.getSn() + "_pwd_" + lockVO.getIndex(), lockVO);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("新增密码异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 修改密码
	 * 
	 * @param accessToken
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updatePassword(SmartLockVO lockVO, Long brandId) {
		try {
			log.info("熙照, 修改密码, vo={}", JSON.toJSONString(lockVO));
			if (StringUtils.isBlank(lockVO.getSn()) || StringUtils.isBlank(lockVO.getPassword())
					|| StringUtils.isBlank(lockVO.getAuthType()) || lockVO.getIndexNum() == null) {
				log.info("参数错误, sn={}, password={}, authType={}, indexNum={}", lockVO.getSn(), lockVO.getPassword(),
						lockVO.getAuthType(), lockVO.getIndexNum());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updatePwd";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", lockVO.getSn());
			map.put("password", LockAESUtil.encryption(lockVO.getPassword(), brand.getSid()));
			map.put("index", lockVO.getIndexNum());

			// 接口调用
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改密码, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码需要缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(lockVO.getSn() + "_pwd_" + lockVO.getIndex(), lockVO);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改密码异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 修改密码有效期
	 * 
	 * @param accessToken
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updatePasswordTime(SmartLockVO lockVO, Long brandId) {
		try {
			log.info("熙照, 修改密码有效期, vo={}", JSON.toJSONString(lockVO));
			if (StringUtils.isBlank(lockVO.getSn()) || StringUtils.isBlank(lockVO.getPassword())
					|| StringUtils.isBlank(lockVO.getAuthType()) || StringUtils.isBlank(lockVO.getStartTime())
					|| StringUtils.isBlank(lockVO.getEndTime())) {
				log.info("参数错误, sn={}, password={}, authType={}, startTime={}, endTime={}", lockVO.getSn(),
						lockVO.getPassword(), lockVO.getAuthType(), lockVO.getStartTime(), lockVO.getEndTime());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updatePwdValidityTime";

			// 封装请求头
			SmartLockApiHeaderVO vo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", lockVO.getSn());
			map.put("startTime",
					DateUtils.format(lockVO.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("endTime",
					DateUtils.format(lockVO.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("index", lockVO.getIndexNum());

			// 接口调用
			String resultStr = httpClient.httpPost(url, vo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改密码有效期, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			if (!result.containsKey("code")) {
				return ResultBean.failedResultOfParamWithMsg(resultStr);
			}

			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码需要缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(lockVO.getSn() + "_pwd_" + lockVO.getIndex(), lockVO);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改密码有效期异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 冻结/解冻密码 （密码、卡片、指纹通用） 注：动态密码(冻结、解冻、删除不支持)
	 * 
	 * @param vo
	 * @param brandId
	 * @param operatorType
	 *            1密码 2卡 3指纹
	 * @return
	 * @author shun
	 * @date 2021年6月26日
	 */
	public ResultBean<String> freezeOrUnfreeze(SmartLockVO vo, Long brandId, Integer operatorType) {
		try {
			if (StringUtils.isBlank(vo.getSn()) || vo.getIndexNum() == null || vo.getSuspend() == null
					|| operatorType == null) {
				log.info("参数错误, sn={}, indexNum={}, suspend={}, operatorType={}", vo.getSn(), vo.getIndexNum(),
						vo.getSuspend(), operatorType);
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			if (vo.getSuspend() == 1 && vo.getLockFrozenId() == null) {
				log.info("参数错误, sn={}, lockFrozenId={}", vo.getSn(), vo.getLockFrozenId());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/freezePwd";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getSn());

			/**
			 * code 密码 adminpwd 管理员密码(删除不支持) dynamicpwd 动态密码(冻结、解冻、删除不支持)
			 * fingerprint 指纹 card 卡片 unknow 未知(冻结、解冻、删除不支持)
			 */
			// 1密码 2卡 3指纹
			if (operatorType == 1) {
				map.put("passwordType", "code");
			} else if (operatorType == 2) {
				map.put("passwordType", "card");
			} else if (operatorType == 3) {
				map.put("passwordType", "fingerprint");
			}

			map.put("index", vo.getIndexNum());
			// 冻结（1）或者解冻（0)
			map.put("enable", vo.getSuspend() == 1 ? true : false);

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 冻结/解冻, enable={}, body={}, result={}", vo.getSuspend() == 1?"冻结":"解冻", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(vo.getSn() + "_freeze_" + vo.getIndexNum(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("冻结/解冻密码异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 删除密码 注：动态密码(冻结、解冻、删除不支持)
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> clearPassword(@RequestBody SmartLockVO vo, Long brandId, String passwordType) {
		try {
			if (StringUtils.isBlank(vo.getSn()) || vo.getIndexNum() == null) {
				log.info("参数错误, sn={}, indexNum={}", vo.getSn(), vo.getIndexNum());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/rmPwd";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getSn());

			/**
			 * code 密码 
			 * adminpwd 管理员密码(删除不支持) 
			 * dynamicpwd 动态密码(冻结、解冻、删除不支持)
			 * fingerprint 指纹 
			 * card 卡片 
			 * unknow 未知(冻结、解冻、删除不支持)
			 */
			map.put("passwordType", passwordType);
			map.put("index", vo.getIndexNum());

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 删除密码, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			
			redisService.putLockCallBack(vo.getSn() + "_del_" + vo.getIndexNum(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("删除密码异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 卡统一处理
	 * 
	 * @param smartLockCard
	 * @param vo
	 * @param brandId
	 * @return
	 * @author shun
	 * @date 2021年7月1日
	 */
	public ResultBean<String> validateOperationTypeAndCardPwd(SmartLockCard smartLockCard, SmartLockVO vo,
			Long brandId) {
		vo.setIndexNum(smartLockCard.getCardIndexNum());
		// 新增
		if (smartLockCard.getId() == null) {
			return operationCardPassword(vo, brandId);
		}

		// 次数不能修改
		if ("5".equals(vo.getAuthType())) {
			return ResultBean.failedResultOfParamWithMsg("设备不支持修改次数");
		}
		// 修改, 如果时间与密码都有调整，一起更新
		updateCard(vo, brandId);

		// 修改时间
		return updateCardTime(vo, brandId);
	}

	/**
	 * 新增卡
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> operationCardPassword(SmartLockVO vo, Long brandId) {
		try {
			if (StringUtils.isBlank(vo.getSn()) || StringUtils.isBlank(vo.getCardId()) || vo.getCardIndex() == null
					|| vo.getTimes() == null || StringUtils.isBlank(vo.getStartTime())
					|| StringUtils.isBlank(vo.getEndTime())) {
				log.info("参数错误, sn={}, cardId={}, cardIndex={}, times={}, startTime={}, endTime={}", vo.getSn(),
						vo.getCardId(), vo.getCardIndex(), vo.getTimes(), vo.getStartTime(), vo.getEndTime());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}
			
			if ("5".equals(vo.getAuthType()) && (vo.getTimes() == null || vo.getTimes() > 1)) {
				if(vo.getTimes() != 1){
					log.info("熙照, 自定义卡次数错误, 不支持自定义次数, sn={}, times={}", vo.getSn(), vo.getTimes());
					return ResultBean.failedResultOfParamWithMsg("锁品牌, 不支持自定义次数");
				}
				return ResultBean.failedResultOfParamWithMsg("卡次数, 参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/saveCard";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();

			map.put("lockId", vo.getSn());
			map.put("card", vo.getCardId());
			map.put("startTime",
					DateUtils.format(vo.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("endTime", DateUtils.format(vo.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));

			map.put("pwdSeq", vo.getCardIndex());
			map.put("times", vo.getTimes());

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 新增卡, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(vo.getSn() + "_card_" + vo.getCardIndex(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("新增卡异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 修改卡
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updateCard(SmartLockVO vo, Long brandId) {
		try {
			if (StringUtils.isBlank(vo.getSn()) || StringUtils.isBlank(vo.getCardId())
					|| vo.getCardIndexNum() == null) {
				log.info("参数错误, sn={}, cardId={}, cardIndex={}, cardIndexNum={}", vo.getSn(), vo.getCardId(),
						vo.getCardIndexNum());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updateCard";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getSn());
			map.put("index", vo.getCardIndexNum());
			map.put("startTime",
					DateUtils.format(vo.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("endTime", DateUtils.format(vo.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改卡, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(vo.getSn() + "_card_" + vo.getCardIndex(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改卡异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 
	 * 修改卡片有效期
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updateCardTime(SmartLockVO vo, Long brandId) {
		try {
			if (StringUtils.isBlank(vo.getSn()) || StringUtils.isBlank(vo.getCardId())
					|| vo.getCardIndexNum() == null) {
				log.info("参数错误, sn={}, cardId={}, cardIndex={}, times={}, startTime={}, endTime={}", vo.getSn(),
						vo.getCardId(), vo.getCardIndexNum());
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updateCardValidityTime";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getSn());
			map.put("index", vo.getCardIndexNum());
			map.put("startTime",
					DateUtils.format(vo.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("endTime", DateUtils.format(vo.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改卡片有效期, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockCallBack(vo.getSn() + "_card_" + vo.getCardIndex(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改卡片有效期异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 指纹统一处理(增加、修改)
	 * 
	 * @param vo
	 * @param fingerprintId
	 * @param brandId
	 * @return
	 * @author shun
	 * @date 2021年7月7日
	 */
	public ResultBean<String> validateOperationFingerprint(SmartLockFingerprintVO vo, Long fingerprintId,
			Long brandId) {
		// 新增
		if (fingerprintId == null) {
			return addFingerprint(vo, brandId);
		}

		// 次数不能修改
		if ("5".equals(vo.getAuthType())) {
			return ResultBean.failedResultOfParamWithMsg("设备不支持修改次数");
		}

		// 修改内容
		updateFingerprint(vo, brandId);

		// 验证是否修改时间
		return updateFingerprintTime(vo, brandId);
	}

	/**
	 * 新增指纹
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> addFingerprint(SmartLockFingerprintVO vo, Long brandId) {
		try {
			if (vo == null || StringUtils.isBlank(vo.getLockId()) || StringUtils.isBlank(vo.getFingerprint())
					|| StringUtils.isBlank(vo.getStartTime()) || StringUtils.isBlank(vo.getEndTime())
					|| vo.getPwdSeq() == null || vo.getTimes() == null || StringUtils.isBlank(vo.getFpModel())) {
				log.info("参数错误, vo={}", JSON.toJSONString(vo));
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}
			
			if ("5".equals(vo.getAuthType()) && (vo.getTimes() == null || vo.getTimes() > 1)) {
				if(vo.getTimes() != 1){
					log.info("熙照, 自定义指纹次数错误, 不支持自定义次数, sn={}, times={}", vo.getLockId(), vo.getTimes());
					return ResultBean.failedResultOfParamWithMsg("锁品牌, 不支持自定义次数");
				}
				return ResultBean.failedResultOfParamWithMsg("指纹次数, 参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/saveFp";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getLockId());
			// 指纹数据
			map.put("fingerprint", vo.getFingerprint());
			// 指纹采集器型号
			map.put("fpModel", vo.getFpModel());
			// 指纹数据 MD5 加密后的数值
			map.put("md5Code", MD5Util.encryption(vo.getFingerprint()));
			// 指纹生效时间
			map.put("startTime", vo.getStartTime());
			// 指纹失效时间
			map.put("endTime", vo.getEndTime());
			// 序号
			map.put("pwdSeq", vo.getPwdSeq());
			// 指纹开锁次数，1 次或多次
			map.put("times", vo.getTimes());

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 新增指纹, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());

			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockFingerprintCallBack(vo.getLockId() + "_fingerprint_" + vo.getPwdSeq(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("新增指纹异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 修改指纹
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updateFingerprint(SmartLockFingerprintVO vo, Long brandId) {
		try {
			if (vo == null || StringUtils.isBlank(vo.getLockId()) || StringUtils.isBlank(vo.getFingerprint())
					|| vo.getIndex() == null) {
				log.info("参数错误, vo={}", JSON.toJSONString(vo));
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updateFp";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getLockId());
			// 指纹数据
			map.put("fingerprint", vo.getFingerprint());
			// 指纹数据 MD5 加密后的数值
			map.put("md5Code", MD5Util.encryption(vo.getFingerprint()));
			map.put("index", vo.getIndexNum());

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改指纹, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockFingerprintCallBack(vo.getLockId() + "_fingerprint_" + vo.getPwdSeq(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改指纹异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}

	/**
	 * 修改指纹有效期
	 * 
	 * @param vo
	 * @return 回调id
	 */
	public ResultBean<String> updateFingerprintTime(SmartLockFingerprintVO vo, Long brandId) {
		try {
			if (vo == null || StringUtils.isBlank(vo.getLockId()) || StringUtils.isBlank(vo.getStartTime())
					|| StringUtils.isBlank(vo.getEndTime()) || vo.getIndex() == null) {
				log.info("参数错误, vo={}", JSON.toJSONString(vo));
				return ResultBean.failedResultOfParamWithMsg("参数错误");
			}

			Optional<SmartLockBrand> optional = smartLockBrandRepository.findById(brandId);
			if (!optional.isPresent()) {
				log.info("设备品牌信息未找, brandId={}", brandId);
				return ResultBean.failedResultOfParamWithMsg("设备品牌信息未找到");
			}

			SmartLockBrand brand = optional.get();
			if (StringUtils.isEmpty(brand.getApiUrl()) || StringUtils.isEmpty(brand.getSid())
					|| StringUtils.isEmpty(brand.getSercret())) {
				log.info("熙照, 设备品牌接口参数为空, url={}, sid={}, sercret={}", brand.getApiUrl(), brand.getSid(),
						brand.getSercret());
				return ResultBean.failedResultOfParamWithMsg("硬件接口参数为空");
			}
			String url = brand.getApiUrl() + "open/smartLock/device/updateFpValidityTime";

			// 封装请求头
			SmartLockApiHeaderVO headerVo = getApiHeader(brand);

			// 请求消息体
			Map<String, Object> map = new HashMap<>();
			map.put("lockId", vo.getLockId());
			// 指纹生效时间
			map.put("startTime",
					DateUtils.format(vo.getStartTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			// 指纹失效时间
			map.put("endTime", DateUtils.format(vo.getEndTime(), DateUtils.FORMAT_14, DateUtils.FORMAT_DATETIME_14));
			map.put("index", vo.getIndexNum());

			// 接口调用
			String resultStr = httpClient.httpPost(url, headerVo, JSON.toJSONString(map));
			JSONObject result = JSONObject.parseObject(resultStr);
			log.info("熙照, 修改指纹有效期, body={}, result={}", JSON.toJSONString(map), JSON.toJSONString(result));
			int code = Integer.parseInt(result.get("code").toString());
			if (code != 0) {
				return ResultBean.failedResultWithMsg(result.getString("message"));
			}
			JSONObject dataObj = result.getJSONObject("data");
			// 熙照只能通过密码序号缓存, 没有回调id
			String taskId = dataObj.get("taskId").toString();
			redisService.putLockFingerprintCallBack(vo.getLockId() + "_fingerprint_" + vo.getPwdSeq(), vo);
			return ResultBean.successfulResult(taskId);
		} catch (Exception e) {
			log.error("修改指纹有效期异常" + e.getMessage(), e);
			return ResultBean.failedResultWithMsg("设备异常, 稍后重试");
		}
	}
}